home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / debug / Common / LazyRegionManager.m < prev    next >
Text File  |  1994-11-29  |  6KB  |  218 lines

  1. #import "LazyRegionManager.h"
  2.  
  3. #import <string.h>
  4.  
  5. #define     VM_PROT_VOLATILE    ((vm_prot_t) 0x08)    // not cacheable
  6. #define         VM_PROT_SPARSE        ((vm_prot_t) 0x10)    // sparse addr space
  7.  
  8. @implementation LazyRegionManager
  9.  
  10. -(BOOL)readInReloc: (Reloc *)reloc
  11. {
  12.     kern_return_t ret;
  13.     
  14.     if (!reloc->rFlags.readIn) {
  15.     ret = vm_allocate(task_self(), &reloc->data, reloc->size, YES);
  16.     if (ret == KERN_SUCCESS) {
  17.         reloc->maxData = reloc->data + reloc->size;
  18.         reloc->displacement = reloc->data - reloc->address;
  19.         reloc->rFlags.readIn = YES;
  20.     }
  21.     }
  22.     return reloc->rFlags.readIn ? YES : NO;
  23. }
  24.  
  25. -(int)pageFor: (const void *)pointer inRegion: (Region *)region
  26. {
  27.     return (((unsigned int)pointer - region->reloc.address) / pageSize);
  28. }
  29.  
  30. -(BOOL)readInDataFor: (const void *)pointer into: (void *)data withSize: (int)size
  31. {
  32.     unsigned int error = 0, nData;
  33.     pointer_t readPage;
  34.     
  35.     error = vm_read(task, (vm_address_t)pointer, size, &readPage, &nData);
  36.     if (!error) {
  37.     bcopy((void *)readPage, data, size);
  38.     vm_deallocate(task_self(), readPage, nData);
  39.     } else
  40.     [self isTask];
  41.     return error ? NO : YES;
  42. }
  43.  
  44. -(BOOL)readInPage: (unsigned char *)page
  45.               for: (void *)pointer
  46.              into: (void *)data
  47. {
  48.     unsigned int error = 0, nData;
  49.     pointer_t readPage;
  50.     
  51.     if (!(*page & PAGEREADIN)) {
  52. //    printf("Reading in page at %p.\n", pointer);
  53.     error = vm_read(task, (vm_address_t)pointer, pageSize, &readPage, 
  54.                     &nData);
  55.     if (!error) {
  56.         bcopy((void *)readPage, data, pageSize);
  57.         vm_deallocate(task_self(), readPage, nData);
  58.         if (!(*page & VM_PROT_VOLATILE))
  59.         *page |= PAGEREADIN;
  60.     } else
  61.         [self isTask];
  62.     }
  63.     return error ? NO : YES;
  64. }
  65.  
  66. -(BOOL)readInPagesFor: (const void *)pointer withSize: (int)size inRegion: (Region *)region
  67. {
  68.     int nPage, offset;
  69.     unsigned char *page, *endPage;
  70.     void *data, *address;
  71.     int ok = YES;
  72.     
  73. //    printf("Getting data at: %p for %d bytes.\n", pointer, size);
  74.     
  75.     nPage = [self pageFor: pointer inRegion: region];
  76.     offset = nPage * pageSize;
  77.     page = region->pages + nPage;
  78.     if (*page & VM_PROT_SPARSE)
  79.     ok = [self readInDataFor: pointer
  80.                         into: (void *)pointer + region->reloc.displacement 
  81.             withSize: size];
  82.     else {
  83.     endPage = region->pages
  84.             + [self pageFor: pointer + size inRegion: region];
  85.     data = (void *)(region->reloc.data + offset);
  86.     address = (void *)(region->reloc.address + offset);
  87.     while (ok && page <= endPage) {
  88.         ok = [self readInPage: page for: address into: data];
  89.         address += pageSize;
  90.         data += pageSize;
  91.         page++;
  92.     }
  93.     }
  94.     return ok;
  95. }
  96.  
  97. -(void *)pointerFor: (const void *)pointer withSize: (int)size
  98. {
  99.     Region *region;
  100.     pointer_t newPointer;
  101.     if (pointer && (region = (Region *)[self relocFor: pointer])) {
  102.     newPointer = (pointer_t)pointer + region->reloc.displacement;
  103.     if (((newPointer + size) <= region->reloc.maxData)
  104.         && [self readInPagesFor: pointer withSize: size inRegion: region])
  105.         return (void *)newPointer;
  106.     else
  107.         return NULL;
  108.     } else
  109.     return NULL;
  110. }
  111.  
  112. -(int)getDataAt: (const void *)start for: (int)numBytes into: (void *)data
  113. {
  114.     Reloc *reloc = [self relocFor: start];
  115.     int numBytesInRegion;
  116.     
  117. //    printf("Getting data at: %p for %d bytes.\n", start, numBytes);
  118.     
  119.     if (reloc) {
  120.         numBytesInRegion = reloc->maxAddress - (int)start;
  121.         if (numBytes > numBytesInRegion)
  122.         numBytes = numBytesInRegion;
  123.     if ([self readInPagesFor: start
  124.                     withSize: numBytes
  125.                 inRegion: (Region *)reloc]) {
  126.         memcpy(data,
  127.             (void *)(reloc->data
  128.                      + ((pointer_t)start - reloc->address)),
  129.             numBytes);
  130.         return numBytes;
  131.     } else
  132.         return 0;
  133.     } else
  134.     return 0;
  135. }
  136.  
  137. -(int)putDataAt: (void *)start for: (int)numBytes from: (const void *)data
  138. {
  139.     int numBytesInRegion;
  140.     Reloc *reloc = [self relocFor: start];
  141.  
  142. //    printf("Putting data at: %p for %d bytes.\n", start, numBytes);
  143.  
  144.     if (reloc) {
  145.         numBytesInRegion = reloc->maxAddress - (int)start;
  146.         if (numBytes > numBytesInRegion)
  147.         numBytes = numBytesInRegion;
  148.     if ([self readInPagesFor: start
  149.                     withSize: numBytes
  150.                 inRegion: (Region *)reloc]) {
  151.         memcpy((void *)(reloc->data + ((pointer_t)start - reloc->address)),
  152.            data,
  153.            numBytes);
  154.         return [self writeDataAt: start for: numBytes
  155.                            reloc: (Region *)reloc];
  156.     } else
  157.         return 0;
  158.     } else
  159.     return 0;
  160. }
  161.  
  162. -(char *)pointerForString: (const char *)pointer isNullTerminated: (BOOL *)isNT
  163. {
  164.     char *retPointer;
  165.     Region *region;
  166.     char *string;
  167.     int nPage, offset;
  168.     unsigned char *page;
  169.     void *data, *address;
  170.     BOOL ok;
  171.     
  172.     if (pointer && (region = (Region *)[self relocFor: pointer])) {
  173.         retPointer = (char *)((pointer_t)pointer + region->reloc.displacement);
  174.     nPage = [self pageFor: pointer inRegion: region];
  175.     page = region->pages + nPage;
  176.     offset = nPage * pageSize;
  177.     data = (void *)(region->reloc.data + offset);
  178.     address = (void *)(region->reloc.address + offset);
  179.     string = retPointer;
  180.     do {
  181.         ok = [self readInPage: page for: address into: data];
  182.         if (ok) {
  183.         page++;
  184.         address += pageSize;
  185.         data += pageSize;
  186.         while (*string && (string < (char *)data))
  187.             string++;
  188.         }
  189.     } while (ok && *string && (data < (void *)region->reloc.maxData));
  190.     *isNT = *string ? NO : YES;
  191.     return retPointer;
  192.     } else{
  193.     *isNT = NO;
  194.     return NULL;
  195.     }
  196. }
  197.  
  198. -(int)writeDataAt: (const void *)start for: (int)numBytes reloc: (Region *)region
  199. {
  200.     char *page = pages + [self pageFor: start inRegion: region];
  201.     kern_return_t ret;
  202.     
  203.     if (*page & VM_PROT_SPARSE) {
  204.     ret = vm_write(task,
  205.                    (vm_address_t)start,
  206.                    (pointer_t)(start + region->reloc.displacement),
  207.                numBytes);
  208.     if (ret == KERN_SUCCESS)
  209.         return numBytes;
  210.     else {
  211.         [self isTask];
  212.         return 0;
  213.     }
  214.     } else
  215.     return [super writeDataAt: start for: numBytes reloc: region];
  216. }
  217.  
  218. @end